home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / oleo-1_4.lha / oleo-1.4 / io-x11.c < prev    next >
C/C++ Source or Header  |  1993-05-21  |  59KB  |  2,576 lines

  1. #ifdef HAVE_X11_X_H
  2. /*    Copyright (C) 1992, 1993 Free Software Foundation, Inc.
  3.     
  4.     This program is free software; you can redistribute it and/or modify
  5.     it under the terms of the GNU General Public License as published by
  6.     the Free Software Foundation; either version 2, or (at your option)
  7.     any later version.
  8.     
  9.     This program is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     GNU General Public License for more details.
  13.     
  14.     You should have received a copy of the GNU General Public License
  15.     along with this software; see the file COPYING.  If not, write to
  16.     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18.  
  19. #include  <stdio.h>
  20. #include <ctype.h>
  21. #include <sys/param.h>
  22. #define NeedFunctionPrototypes 0
  23. #include <X11/X.h>
  24. #include <X11/Xlib.h>
  25. #include <X11/Xutil.h>
  26. #include <X11/Xresource.h>
  27. #include <X11/keysym.h>
  28. #include "global.h"
  29. #include "utils.h"
  30. #include "io-generic.h"
  31. #include "io-edit.h"
  32. #include "io-utils.h"
  33. #include "io-term.h"
  34. #include "cmd.h"
  35. #include "window.h"
  36. #include "line.h"
  37. #include "font.h"
  38. #include "lists.h"
  39. #include "ir.h"
  40. #include "display.h"
  41. #include "io-abstract.h"
  42. #include "regions.h"
  43. #include "input.h"
  44. #include "info.h"
  45.  
  46.  
  47. #if defined(HAVE_RINT)
  48. #ifdef __STDC__
  49. extern double rint (double);
  50. #else
  51. extern double rint ();
  52. #endif
  53. #else
  54. #define rint(x) (((x)<0) ? ceil((x)-.5) : floor((x)+.5))
  55. #endif
  56. static void record_damage ();
  57.  
  58. #ifdef __STDC__
  59. extern char * x_get_string_resource (XrmDatabase, char *, char *);
  60. extern XrmDatabase x_load_resources (Display *, char *, char *);
  61. extern char * getenv (const char *);
  62. #else
  63. extern char * x_get_string_resource ();
  64. extern XrmDatabase x_load_resources ();
  65. extern char * getenv ();
  66. #endif
  67.  
  68.  
  69. static char *emergency_font_name = "8x13";
  70. static char *cell_font_name = "times_roman12";
  71. static char *default_font_name = "8x13";
  72. static char *input_font_name = "8x13";
  73. static char *status_font_name = "6x10";
  74. static char *text_line_font_name = "8x13";
  75. static char *label_font_name = "5x8";
  76. int cell_font_point_size = 12;
  77. static char *default_bg_color_name = "black";
  78. static char *default_fg_color_name = "white";
  79.  
  80. /* If non-0 and !no_x, these display functions will be used. */
  81. char *io_x11_display_name = 0;
  82.  
  83. /* The geometry of the first window. */
  84. static int geom_x = 0;
  85. static int geom_y = 0;
  86. static int geom_w = 675;
  87. static int geom_h = 350;
  88. static char geom_string[] = "675x350+0+0";
  89.  
  90. /* This global is used only during command line and .Xdefaults handling. */
  91. static Display * theDisplay;
  92.  
  93. static char * rdb_class_name = "Oleo";
  94. static char * rdb_name = "oleo";
  95.  
  96. #if 0
  97. static XrmOptionDescRec x11_options[] =
  98. {
  99.   {0, 0, 0, 0}
  100. };
  101.  
  102. /* This dynamicly computes the size of x11_options to make 
  103.  * upkeep of this file less error prone.
  104.  */
  105. static int
  106.   count_options ()
  107. {
  108.   int x;
  109.   for (x = 0; x11_options[x].option; ++x)
  110.     ;
  111.   return x;
  112. }
  113. #endif
  114. /* This synthesizes class and generic names for resources (fancy strcat).
  115.  * Memory is reused after a reasonable number of calls. 
  116.  */
  117. #define RDB_NAME_BUF    8
  118. #define RDB_NAME_SIZE    256
  119.  
  120. #ifdef __STDC__
  121. static char * 
  122. resource_name (char * left, char * right)
  123. #else
  124. static char * 
  125. resource_name (left, right)
  126.      char * left;
  127.      char * right;
  128. #endif
  129. {
  130.   static char bufs[RDB_NAME_BUF][RDB_NAME_SIZE];
  131.   static int buf_pos = 0;
  132.   int len = strlen(left);
  133.   
  134.   if (len)
  135.     bcopy (left, bufs[buf_pos], len);
  136.   bufs[buf_pos][len] = '.';
  137.   strcpy (bufs[buf_pos] + len + 1, right);
  138.   return bufs [buf_pos++];
  139. }
  140.  
  141. #ifdef __STDC__
  142. static char *
  143. class_of (char * foo)
  144. #else
  145. static char *
  146. class_of (foo)
  147.      char * foo;
  148. #endif
  149. {
  150.   return resource_name (rdb_class_name, foo);
  151. }
  152.  
  153. #ifdef __STDC__
  154. static char *
  155. name_of (char * foo)
  156. #else
  157. static char *
  158. name_of (foo)
  159.      char * foo;
  160. #endif
  161. {
  162.   return resource_name (rdb_name, foo);
  163. }
  164.  
  165. static XrmDatabase rdb;
  166.  
  167. #ifdef __STDC__
  168. void
  169. get_x11_args (int * argc_p, char ** argv)
  170. #else
  171. void
  172. get_x11_args (argc_p, argv)
  173.      int * argc_p;
  174.      char ** argv;
  175. #endif
  176. {
  177.   XrmInitialize ();
  178.   
  179. #if 0
  180.   XrmDatabase argv_resources;
  181.   /* Get the command line arguments. */
  182.   XrmParseCommand (&argv_resources, x11_options,
  183.            count_options (x11_options),
  184.            rdb_name, argc_p, argv);
  185.   
  186.   /* Compute the display from either resources or getenv. */
  187.   
  188.   io_x11_display_name =
  189.     x_get_string_resource (argv_resources, class_of ("Display"),
  190.                name_of ("display"));
  191. #endif                           
  192.   if (!io_x11_display_name)
  193.     io_x11_display_name = ck_savestr (getenv ("DISPLAY"));
  194.   
  195.   if (!io_x11_display_name)
  196.     return;
  197.   
  198.   theDisplay = XOpenDisplay (io_x11_display_name);
  199.   if (!theDisplay)
  200.     panic ("Can not connect to X.  Check your DISPLAY evironment variable.");
  201.   
  202.   FD_SET (ConnectionNumber (theDisplay), &read_fd_set);
  203.   FD_SET (ConnectionNumber (theDisplay), &exception_fd_set);
  204.   
  205.   /* Load the resource databases in a manner not unlike emacs :). */
  206.   rdb = x_load_resources (theDisplay, 0, rdb_class_name);
  207.   
  208. #if 0
  209.   /* Merge in the command line database.  */
  210.   XrmMergeDatabases (argv_resources, rdb);
  211. #endif
  212.   
  213.   /* Set up the various defaults (staticly declared above). */
  214.   {
  215.     char * val;
  216.     
  217.     val = x_get_string_resource (rdb, class_of ("Foreground"),
  218.                  name_of("foreground"));
  219.     if (val)
  220.       default_fg_color_name = val;
  221.     
  222.     val = x_get_string_resource (rdb, class_of ("Background"),
  223.                  name_of("background"));
  224.     if (val)
  225.       default_bg_color_name = val;
  226.     
  227.     val = x_get_string_resource (rdb, class_of ("Geometry"),
  228.                  name_of("geometry"));
  229.     if (val)
  230.       XGeometry (theDisplay, DefaultScreen(theDisplay), val, geom_string,
  231.          0, 1, 1, 0, 0, &geom_x, &geom_y, &geom_w, &geom_h);
  232.   }
  233. }
  234.  
  235.  
  236. static int x11_opened = 0;
  237. static struct sXport *thePort;
  238. typedef struct sXport *Xport;
  239.  
  240. struct sXport
  241. {
  242.   Display *dpy;
  243.   int screen;
  244.   Colormap color_map;
  245.   XColor fg_color;
  246.   XColor bg_color;
  247.   unsigned long fg_color_pixel;
  248.   unsigned long bg_color_pixel;
  249.   Window window;
  250.   Cursor mouse_cursor;
  251.   
  252.   XFontStruct *input_font;
  253.   XFontStruct *text_line_font;
  254.   XFontStruct *label_font;
  255.   XFontStruct *status_font;
  256.   
  257.   GC neutral_gc;
  258.   GC normal_gc;
  259.   GC standout_gc;
  260.   GC input_gc;
  261.   GC standout_input_gc;
  262.   GC text_line_gc;
  263.   GC text_line_standout_gc;
  264.   GC label_gc;
  265.   GC label_standout_gc;
  266.   GC status_gc;
  267.   
  268.   struct x_window *xwins;
  269.   int cursor_visible;        /* init to 1 */
  270.   int redisp_needed;
  271.   Atom wm_delete_window;
  272.   
  273.   /* The state of the input area. */
  274.   struct input_view input_view;
  275. };
  276.  
  277. #ifdef __STDC__
  278. static void
  279. beep (Xport xport)
  280. #else
  281. static void
  282. beep (xport)
  283.      Xport xport;
  284. #endif
  285. {
  286. #if 0
  287.   XBell (xport->dpy, 30);
  288.   XFlush (xport->dpy);
  289. #endif
  290. }
  291.  
  292. #ifdef __STDC__
  293. static void
  294. xio_bell (void)
  295. #else
  296. static void
  297. xio_bell ()
  298. #endif
  299. {
  300.   beep (thePort);
  301. }
  302.  
  303.  
  304. #ifdef __STDC__
  305. static void
  306. draw_text_item (Xport xport, int c, int r, int wid, int hgt,
  307.         XFontStruct *font, GC gc, XTextItem *text, int do_clip)
  308. #else
  309. static void
  310. draw_text_item (xport, c, r, wid, hgt, font, gc, text, do_clip)
  311.      Xport xport;
  312.      int c;
  313.      int r;
  314.      int wid;
  315.      int hgt;
  316.      XFontStruct *font;
  317.      GC gc;
  318.      XTextItem *text;
  319.      int do_clip;
  320. #endif
  321. {
  322.   XRectangle clip;
  323.   int widused;
  324.   int tab_char;
  325.   XTextItem to_draw;
  326.  
  327.   clip.x = c;
  328.   clip.y = r;
  329.   clip.width = wid;
  330.   clip.height = hgt;
  331.   if (!x11_opened)
  332.     return;
  333.   if (do_clip)
  334.     XSetClipRectangles (xport->dpy, gc, 0, 0, &clip, 1, YXBanded);
  335.  
  336.  
  337.   tab_char = 0;
  338.   to_draw = *text;
  339.   widused = 0;
  340.   while (to_draw.nchars)
  341.     {
  342.       XTextItem draw_now;
  343.       XTextItem after_tab;
  344.  
  345.       /* Draw tab characters carefully. */
  346.       {
  347.     int x;
  348.     for (x = 0; x < to_draw.nchars; ++x)
  349.       if (to_draw.chars[x] == '\t')
  350.         {
  351.           draw_now = to_draw;
  352.           draw_now.nchars = x;
  353.           after_tab = to_draw;
  354.           after_tab.chars += x + 1;
  355.           after_tab.nchars -= x + 1;
  356.           goto draw_burst;
  357.         }
  358.     /* No tabs found. */
  359.     draw_now = to_draw;
  360.     bzero (&after_tab, sizeof (after_tab));
  361.       }
  362.  
  363.     draw_burst:
  364.       XDrawImageString (xport->dpy, xport->window, gc,
  365.             c + widused, r + font->ascent,
  366.             draw_now.chars, draw_now.nchars);
  367.       widused += XTextWidth (font, draw_now.chars, draw_now.nchars);
  368.       tab_char += draw_now.nchars;
  369.       if (after_tab.chars)
  370.     {
  371.       int tab_stop_col = ((tab_char + 8 - tab_char % 8)
  372.                   * font->max_bounds.width);
  373.       XFillRectangle (xport->dpy, xport->window, xport->neutral_gc,
  374.               c + widused, r, tab_stop_col - widused, hgt);
  375.       widused = tab_stop_col;
  376.       tab_char += 8 - tab_char % 8;
  377.     }
  378.       to_draw = after_tab;
  379.     }
  380.  
  381.   if (widused < wid)
  382.     XFillRectangle (xport->dpy, xport->window, xport->neutral_gc,
  383.             c + widused, r, wid - widused, hgt);
  384.   if (do_clip)
  385.     XSetClipMask (xport->dpy, gc, None);
  386. }
  387.  
  388. #ifdef __STDC__
  389. static void
  390. xio_redraw_input_cursor (int on)
  391. #else
  392. static void
  393. xio_redraw_input_cursor (on)
  394.      int on;
  395. #endif
  396. {
  397.   struct input_view * iv = &thePort->input_view;
  398.   int offset = iv->input_cursor - iv->visibility_begin;
  399.   int start;
  400.   XTextItem cursor_text;
  401.   int cwid;
  402.   int ypos = (iv->current_info ? 0 : input);
  403.   char * inp;
  404.  
  405.   inp = (iv->input_area
  406.      ? iv->input_area->buf + iv->visibility_begin
  407.      : "");
  408.   start = (XTextWidth (thePort->input_font, inp, offset) + iv->prompt_wid);
  409.  
  410.   cursor_text.font = thePort->input_font->fid;
  411.   cursor_text.nchars = 1;
  412.   if (iv->input_cursor <= iv->visibility_end)
  413.     {
  414.       cwid = XTextWidth (thePort->input_font, inp + offset, 1);
  415.       cursor_text.chars = inp + offset;
  416.     }
  417.   else
  418.     {
  419.       cwid = XTextWidth (thePort->input_font, " ", 1);
  420.       cursor_text.chars = " ";
  421.     }
  422.   draw_text_item (thePort, start, ypos, cwid, input_rows,
  423.           thePort->input_font,
  424.           (on ? thePort->standout_input_gc : thePort->input_gc),
  425.           &cursor_text, 1);
  426. }
  427.  
  428. #ifdef __STDC__
  429. static void
  430. xio_cellize_cursor (void)
  431. #else
  432. static void
  433. xio_cellize_cursor ()
  434. #endif
  435. {
  436.   xio_redraw_input_cursor (0);
  437. }
  438.  
  439. #ifdef __STDC__
  440. static void
  441. xio_inputize_cursor (void)
  442. #else
  443. static void
  444. xio_inputize_cursor ()
  445. #endif
  446. {
  447.   xio_redraw_input_cursor (1);
  448. }
  449.  
  450. static int
  451. x_input_metric (str, len)
  452.      char * str;
  453.      int len;
  454. {
  455.   return XTextWidth (thePort->input_font, str, len);
  456. }
  457.  
  458. /* This redraws the input area without recomputing anything. */
  459. #ifdef __STDC__
  460. static void
  461. xio_redraw_input (void)
  462. #else
  463. static void
  464. xio_redraw_input ()
  465. #endif
  466. {
  467.   {
  468.     struct input_view * iv = &thePort->input_view;
  469.     int ypos = (iv->current_info ? 0 : input);
  470.  
  471.     if (iv->redraw_needed == NO_REDRAW)
  472.       return;
  473.     if (iv->redraw_needed == FULL_REDRAW)
  474.       {
  475.     XTextItem text;
  476.     if (iv->expanded_keymap_prompt)
  477.       {
  478.         text.font = thePort->input_font->fid;
  479.         text.chars = iv->expanded_keymap_prompt;
  480.         text.nchars = strlen (iv->expanded_keymap_prompt);
  481.         draw_text_item (thePort,
  482.                 0, ypos, scr_cols, input_rows,
  483.                 thePort->input_font, thePort->input_gc,
  484.                 &text, 0);
  485.         iv->redraw_needed = NO_REDRAW;
  486.         if (input_active || iv->current_info)
  487.           xio_redraw_input_cursor (1);
  488.         return;
  489.       }
  490.     else if (iv->prompt_wid)
  491.       {
  492.         text.font = thePort->input_font->fid;
  493.         text.chars = iv->prompt;
  494.         text.nchars = prompt_len (text.chars);
  495.         draw_text_item (thePort, 0, ypos, iv->prompt_wid, input_rows,
  496.                 thePort->input_font, thePort->input_gc,
  497.                 &text, 0);
  498.       }
  499.       }
  500.     
  501.     if (!iv->input_area
  502.     || (iv->visibility_begin > iv->visibility_end))
  503.       {
  504.     XFillRectangle (thePort->dpy, thePort->window, thePort->neutral_gc,
  505.             iv->prompt_wid, ypos,
  506.             scr_cols - iv->prompt_wid, input_rows);
  507.     iv->redraw_needed = NO_REDRAW;
  508.     return;
  509.       }
  510.     
  511.     
  512.     if (iv->visibility_end >= iv->visibility_begin)
  513.       {
  514.     int pos = ((iv->redraw_needed == FULL_REDRAW)
  515.            ? iv->visibility_begin
  516.            : iv->redraw_needed);
  517.  
  518.     int xpos = (iv->prompt_wid
  519.             + XTextWidth (thePort->input_font,
  520.                   iv->input_area->buf + iv->visibility_begin,
  521.                   pos - iv->visibility_begin));
  522.     int wid = scr_cols - xpos;
  523.     int hgt = input_rows;
  524.  
  525.     XTextItem text;
  526.  
  527.     text.font = thePort->input_font->fid;
  528.     text.chars = iv->input_area->buf + pos;
  529.     text.nchars = iv->visibility_end - pos + 1;
  530.  
  531.     draw_text_item (thePort, xpos, ypos, wid, hgt, 
  532.             thePort->input_font, thePort->input_gc,
  533.             &text, 0);
  534.  
  535.     if (input_active || iv->current_info)
  536.       xio_redraw_input_cursor (1);
  537.     iv->redraw_needed = NO_REDRAW;
  538.       }
  539.   }
  540. }
  541.  
  542.  
  543. #ifdef __STDC__
  544. static void
  545. xio_fix_input (void)
  546. #else
  547. static void
  548. xio_fix_input ()
  549. #endif
  550. {
  551.   iv_fix_input (&thePort->input_view);
  552. }
  553.  
  554. #ifdef __STDC__
  555. static void
  556. xio_move_cursor (void)
  557. #else
  558. static void
  559. xio_move_cursor ()
  560. #endif
  561. {
  562.   if (input_active)
  563.     xio_redraw_input_cursor (0);
  564.   iv_move_cursor (&thePort->input_view);
  565.   if (input_active)
  566.     xio_redraw_input_cursor (1);
  567. }
  568.  
  569. #ifdef __STDC__
  570. static void
  571. xio_erase (int len)
  572. #else
  573. static void
  574. xio_erase (len)
  575.      int len;
  576. #endif
  577. {
  578.   iv_erase (&thePort->input_view, len);
  579. }
  580.  
  581. #ifdef __STDC__
  582. static void
  583. xio_insert (int len)
  584. #else
  585. static void
  586. xio_insert (len)
  587.      int len;
  588. #endif
  589. {
  590.   iv_insert (&thePort->input_view, len);
  591. }
  592.        
  593. #ifdef __STDC__
  594. static void
  595. xio_over (char * str, int len)
  596. #else
  597. static void
  598. xio_over (str, len)
  599.      char * str;
  600.      int len;
  601. #endif
  602. {
  603.   iv_over (&thePort->input_view, len);
  604. }
  605.  
  606. #ifdef __STDC__
  607. int
  608. io_col_to_input_pos (int c)
  609. #else
  610. int
  611. io_col_to_input_pos (c)
  612.      int c;
  613. #endif
  614. {
  615.   struct input_view * iv = &thePort->input_view;
  616.   char * prompt = (iv->expanded_keymap_prompt
  617.            ? iv->expanded_keymap_prompt
  618.            : (iv->prompt ? iv->prompt : ""));
  619.   int prompt_wid = iv->prompt_metric (prompt, strlen(prompt));
  620.  
  621.   c -= prompt_wid;
  622.   {
  623.     int cpos;
  624.     int max = iv->visibility_end - iv->visibility_begin + 1;
  625.     for (cpos = 1; cpos < max; ++cpos)
  626.       if (iv->input_metric (iv->input_area->buf + iv->visibility_begin, cpos)
  627.       >= c)
  628.     break;
  629.     return iv->visibility_begin + cpos - 1;
  630.   }
  631. }
  632.  
  633.  
  634. /****************************************************************
  635.  * Low level Input
  636.  ****************************************************************/
  637.  
  638. /* To be like curses, we offer this option: */
  639. static int block_on_getch = 1;
  640.  
  641. /* This is the buffer of decoded keyboard events. */
  642. static char *input_buf = 0;
  643. static int input_buf_allocated = 0;
  644. static int chars_buffered = 0;
  645. #define MAX_KEY_TRANSLATION    (1024)
  646.  
  647. static XComposeStatus compose;
  648.  
  649. #ifdef __STDC__
  650. static void
  651. xio_scan_for_input (int blockp)
  652. #else
  653. static void
  654. xio_scan_for_input (blockp)
  655.      int blockp;
  656. #endif
  657. {
  658.   XEvent event_return;
  659.   static int pendingw;
  660.   static int pendingh;
  661.   static int resize_pending = 0;
  662.   int events_pending;
  663.   int len;
  664.   
  665.   events_pending = XPending (thePort->dpy);
  666.   do
  667.     {
  668.       if (resize_pending && !events_pending)
  669.     {
  670.       if (   ((pendingh / height_scale) > 9.)
  671.           && ((pendingw / width_scale) > 9.))
  672.           {
  673.         io_set_scr_size (pendingh, pendingw);
  674.         resize_pending = 0;
  675.           }
  676.     }
  677.       
  678.       if (!events_pending)
  679.     io_redisp ();
  680.       
  681.       if (events_pending || blockp)
  682.     XNextEvent (thePort->dpy, &event_return);
  683.       else
  684.     return;
  685.       
  686.       switch (event_return.type)
  687.     {
  688.     case ClientMessage:
  689.       if (event_return.xclient.data.l[0] == thePort->wm_delete_window)
  690.         {
  691.           XCloseDisplay(thePort->dpy);
  692.           exit(0);
  693.         }
  694.       break;
  695.     case KeyPress:
  696.     case ButtonPress:
  697.     case ButtonRelease:
  698.       if (chars_buffered + MAX_KEY_TRANSLATION >= input_buf_allocated)
  699.         {
  700.           input_buf_allocated =
  701.         2 * (input_buf_allocated
  702.              ? input_buf_allocated
  703.              : MAX_KEY_TRANSLATION);
  704.           input_buf =
  705.         (char *) ck_remalloc (input_buf, input_buf_allocated);
  706.         }
  707.     }
  708.       
  709.       
  710.       switch (event_return.type)
  711.     {
  712.     case KeyPress:
  713.       len = XLookupString (&event_return,
  714.                    input_buf + chars_buffered,
  715.                    MAX_KEY_TRANSLATION, 0, &compose);
  716.       if ((len == 1) && (event_return.xkey.state & Mod1Mask))
  717.         input_buf[chars_buffered] |= 0x80;
  718.       chars_buffered += len;
  719.       break;
  720.       
  721.     case ButtonPress:
  722.     case ButtonRelease:
  723.       {
  724.         int seq =
  725.           enqueue_mouse_event (event_return.xbutton.y,
  726.                    event_return.xbutton.x,
  727.                    event_return.xbutton.button,
  728.                    event_return.type == ButtonPress);
  729.         input_buf[chars_buffered++] = MOUSE_CHAR;
  730.         input_buf[chars_buffered++] =
  731.           event_return.xbutton.button - 1 + '0';
  732.         input_buf[chars_buffered++] = (char) seq;
  733.         break;
  734.       }
  735.       
  736.     case Expose:
  737.       record_damage (thePort,
  738.              event_return.xexpose.x, event_return.xexpose.y,
  739.              event_return.xexpose.width,
  740.              event_return.xexpose.height);
  741.       break;
  742.       
  743.     case MapNotify:
  744.       break;
  745.       
  746.     case ReparentNotify:
  747.       break;
  748.       
  749.     case ConfigureNotify:
  750.       pendingw = event_return.xconfigure.width;
  751.       pendingh = event_return.xconfigure.height;
  752.       resize_pending = 1;
  753.       break;
  754.       
  755.     default:
  756.       break;
  757.     }
  758.       events_pending = XPending (thePort->dpy);
  759.     }
  760.   while (events_pending || !chars_buffered);
  761. }
  762.  
  763.  
  764. #ifdef __STDC__
  765. static int
  766. xio_input_avail (void)
  767. #else
  768. static int
  769. xio_input_avail ()
  770. #endif
  771. {
  772.   return chars_buffered;
  773. }
  774.  
  775. #ifdef __STDC__
  776. static void
  777. xio_wait_for_input (void)
  778. #else
  779. static void
  780. xio_wait_for_input ()
  781. #endif
  782. {
  783.   io_scan_for_input (1);
  784. }
  785.  
  786. #ifdef __STDC__
  787. static int
  788. xio_read_kbd (VOLATILE char *buffer, int size)
  789. #else
  790. static int
  791. xio_read_kbd (buffer, size)
  792.      VOLATILE char *buffer;
  793.      int size;
  794. #endif
  795. {
  796.   int amt_read = size < chars_buffered ? size : chars_buffered;
  797.   if (amt_read)
  798.     bcopy (input_buf, (char *) buffer, amt_read);
  799.   chars_buffered -= amt_read;
  800.   if (chars_buffered)
  801.     bcopy ((char *) input_buf + amt_read, (char *) input_buf, chars_buffered);
  802.   return amt_read;
  803. }
  804.  
  805. #ifdef __STDC__
  806. static void
  807. xio_nodelay (int delayp)
  808. #else
  809. static void
  810. xio_nodelay (delayp)
  811.      int delayp;
  812. #endif
  813. {
  814.   block_on_getch = delayp;
  815. }
  816.  
  817. #ifdef __STDC__
  818. static int
  819. xio_getch (void)
  820. #else
  821. static int
  822. xio_getch ()
  823. #endif
  824. {
  825.   char buf;
  826.   
  827.   if (!chars_buffered)
  828.     io_scan_for_input (block_on_getch);
  829.   
  830.   if (chars_buffered)
  831.     {
  832.       io_read_kbd (&buf, 1);
  833.       return buf;
  834.     }
  835.   else
  836.     return 0;
  837. }
  838.  
  839.  
  840. /****************************************************************
  841.  * Low level support for input and status areas.
  842.  ****************************************************************/
  843.  
  844. /*
  845.  * CRAM tells how many characters of a string will fit within
  846.  * a given number of cols, presuming that if they don't all fit,
  847.  * the string CONTINUE must be added to the end of those that do.
  848.  */
  849. #ifdef __STDC__
  850. static int
  851. cram (int cols, XFontStruct *font, char *text, int len, char *continuation)
  852. #else
  853. static int
  854. cram (cols, font, text, len, continuation)
  855.      int cols;
  856.      XFontStruct *font;
  857.      char *text;
  858.      int len;
  859.      char *continuation;
  860. #endif
  861. {
  862.   int cont_cols = XTextWidth (font, continuation, strlen (continuation));
  863.   int cols_used = 0;
  864.   int x = 0;
  865.   
  866.   if (XTextWidth (font, text, len) < cols)
  867.     return len;
  868.   
  869.   cols_used = 0;
  870.   while (x < len && cols_used < (cols - cont_cols))
  871.     cols_used += XTextWidth (font, text + x, 1);
  872.   
  873.   return x;
  874. }
  875.  
  876.  
  877.  
  878.  
  879. #ifdef __STDC__
  880. static void
  881. set_text (XTextItem *xtext, char *text, int len)
  882. #else
  883. static void
  884. set_text (xtext, text, len)
  885.      XTextItem *xtext;
  886.      char *text;
  887.      int len;
  888. #endif
  889. {
  890.   if (xtext->nchars < len)
  891.     {
  892.       xtext->chars = ck_remalloc (xtext->chars, len);
  893.       xtext->nchars = len;
  894.     }
  895.   if (len)
  896.     bcopy (text, xtext->chars, len);
  897.   while (len < xtext->nchars)
  898.     xtext->chars[len++] = ' ';
  899. }
  900.  
  901.  
  902.  
  903. /* The input area. */
  904.  
  905.  
  906.  
  907.  
  908.  
  909.  
  910. /*
  911.  * Low level interface to the input area specificly.
  912.  */
  913.  
  914. static XTextItem input_text;
  915. static int term_cursor_visible = 0;
  916. static int input_cursor = 0;    /* Position of cursor, if visible */
  917. static int textout;
  918. static int input_more_mode = 0;
  919.  
  920. #ifdef __STDC__
  921. static void
  922. draw_input (void)
  923. #else
  924. static void
  925. draw_input ()
  926. #endif
  927. {
  928.   if (!input_text.chars)
  929.     {
  930.       XFillRectangle (thePort->dpy, thePort->window, thePort->neutral_gc,
  931.               input, 0, scr_cols, input_rows);
  932.       return;
  933.     }
  934.   input_text.font = thePort->input_font->fid;
  935.   draw_text_item (thePort, 0, input, scr_cols, input_rows, thePort->input_font,
  936.           thePort->input_gc, &input_text, 1);
  937.   if (input_more_mode)
  938.     {
  939.       XTextItem more_text;
  940.       int mwid = XTextWidth (thePort->input_font, "[more]", 6);
  941.       more_text.chars = "[MORE]";
  942.       more_text.nchars = 6;
  943.       more_text.delta = 0;
  944.       more_text.font = thePort->input_font->fid;
  945.       draw_text_item (thePort, scr_cols - mwid, input, mwid, input_rows,
  946.               thePort->input_font, thePort->standout_input_gc,
  947.               &more_text, 1);
  948.     }
  949.   else if (term_cursor_visible)
  950.     {
  951.       int start = XTextWidth (thePort->input_font, input_text.chars, input_cursor);
  952.       int cwid = XTextWidth (thePort->input_font,
  953.                  input_text.chars + input_cursor, 1);
  954.       XTextItem cursor_text;
  955.       cursor_text.chars = input_text.chars + input_cursor;
  956.       cursor_text.nchars = 1;
  957.       cursor_text.font = thePort->input_font->fid;
  958.       draw_text_item (thePort, start, input, cwid, input_rows,
  959.               thePort->input_font, thePort->standout_input_gc,
  960.               &cursor_text, 1);
  961.     }
  962. }
  963.  
  964.  
  965. #ifdef __STDC__
  966. static void
  967. xio_clear_input_before (void)
  968. #else
  969. static void
  970. xio_clear_input_before ()
  971. #endif
  972. {
  973.   textout = 0;
  974.   if (topclear == 2)
  975.     {
  976.       int x;
  977.       for (x = 0; x < input_text.nchars; ++x)
  978.     input_text.chars[x] = ' ';
  979.       input_cursor = 0;
  980.       draw_input ();
  981.       topclear = 0;
  982.     }
  983. }
  984.  
  985. #ifdef __STDC__
  986. static void
  987. xio_clear_input_after (void)
  988. #else
  989. static void
  990. xio_clear_input_after ()
  991. #endif
  992. {
  993.   if (topclear)
  994.     {
  995.       int x;
  996.       for (x = 0; x < input_text.nchars; ++x)
  997.     input_text.chars[x] = ' ';
  998.       input_cursor = 0;
  999.       draw_input ();
  1000.       topclear = 0;
  1001.     }
  1002. }
  1003.  
  1004. #ifdef __STDC__
  1005. static void
  1006. set_input (char *text, int len, int cursor)
  1007. #else
  1008. static void
  1009. set_input (text, len, cursor)
  1010.      char *text;
  1011.      int len;
  1012.      int cursor;
  1013. #endif
  1014. {
  1015.   set_text (&input_text, text, len);
  1016.   if (cursor + 1 > input_text.nchars)
  1017.     {
  1018.       input_text.chars = (char *) ck_remalloc (input_text.chars, cursor + 1);
  1019.       while (input_text.nchars < cursor + 1)
  1020.     input_text.chars[input_text.nchars++] = ' ';
  1021.     }
  1022.   input_cursor = cursor;
  1023.   draw_input ();
  1024. }
  1025.  
  1026.  
  1027. /*
  1028.  * Low level interface to the status area specificly.
  1029.  */
  1030. static XTextItem status_text;
  1031.  
  1032. #ifdef __STDC__
  1033. static void
  1034. draw_status (void)
  1035. #else
  1036. static void
  1037. draw_status ()
  1038. #endif
  1039. {
  1040.   if (!x11_opened || thePort->input_view.current_info)
  1041.     return;
  1042.   if (user_status)
  1043.     draw_text_item (thePort, 0, status, scr_cols,
  1044.             status_rows, thePort->status_font,
  1045.             thePort->status_gc, &status_text, 1);
  1046. }
  1047.  
  1048. #ifdef __STDC__
  1049. static void
  1050. set_status (char *text)
  1051. #else
  1052. static void
  1053. set_status (text)
  1054.      char *text;
  1055. #endif
  1056. {
  1057.   set_text (&status_text, text, strlen (text));
  1058.   status_text.font = thePort->status_font->fid;
  1059.   draw_status ();
  1060. }
  1061.  
  1062.  
  1063. /****************************************************************
  1064.  * High level interfaces for the input and status areas.
  1065.  ****************************************************************/
  1066.  
  1067. #ifdef __STDC__
  1068. static void
  1069. xio_update_status (void)
  1070. #else
  1071. static void
  1072. xio_update_status ()
  1073. #endif
  1074. {
  1075.   CELL *cp;
  1076.   char *dec;
  1077.   char *ptr;
  1078.   int plen;
  1079.   int dlen;
  1080.   int mplen;
  1081.   char buf[1024];
  1082.   char *assembled;
  1083.   char *pos = buf;
  1084.   
  1085.   if (!user_status)
  1086.     return;
  1087.   
  1088.   if (mkrow != NON_ROW)
  1089.     {
  1090.       struct rng r;
  1091.       *pos++ = '*';
  1092.       set_rng (&r, curow, cucol, mkrow, mkcol);
  1093.       ptr = range_name (&r);
  1094.     }
  1095.   else
  1096.     ptr = cell_name (curow, cucol);
  1097.   if (*ptr)
  1098.     bcopy (ptr, pos, strlen (ptr));
  1099.   pos += strlen (ptr);
  1100.   if (how_many != 1)
  1101.     {
  1102.       sprintf (pos, " {%d}", how_many);
  1103.       pos += strlen (pos);
  1104.     }
  1105.   *pos++ = ' ';
  1106.   mplen = XTextWidth (thePort->status_font, buf, pos - buf);
  1107.   
  1108.   if ((cp = find_cell (curow, cucol)) && cp->cell_formula)
  1109.     {
  1110.       dec = decomp (curow, cucol, cp);
  1111.       dlen = XTextWidth (thePort->status_font, dec, strlen (dec));
  1112.     }
  1113.   else
  1114.     {
  1115.       dec = 0;
  1116.       dlen = 0;
  1117.     }
  1118.   
  1119.   ptr = cell_value_string (curow, cucol);
  1120.   plen = XTextWidth (thePort->status_font, ptr, strlen (ptr));
  1121.   
  1122.   assembled = (char *) ck_malloc (plen + dlen + mplen);
  1123.   if (pos - buf)
  1124.     bcopy (buf, assembled, pos - buf);
  1125.   pos = assembled + (pos - buf);
  1126.   
  1127.   {
  1128.     int c;
  1129.     int l;
  1130.     int wid;
  1131.     
  1132.     l = strlen (ptr);
  1133.     c = cram (scr_cols - mplen - thePort->status_font->max_bounds.width,
  1134.           thePort->status_font, ptr, l, (dec ? " [...]" : "..."));
  1135.     if (c)
  1136.       bcopy (ptr, pos, c);
  1137.     pos += c;
  1138.     if (c == l)
  1139.       *pos++ = ' ';
  1140.     else if (dec)
  1141.       {
  1142.     bcopy (" [...]", pos, 6);
  1143.     pos += 6;
  1144.     dec = 0;
  1145.     dlen = 0;
  1146.     decomp_free ();
  1147.       }
  1148.     else
  1149.       {
  1150.     bcopy ("...", pos, 3);
  1151.     pos += 3;
  1152.       }
  1153.     *pos++ = ' ';
  1154.     wid = XTextWidth (thePort->status_font, assembled, pos - assembled);
  1155.     
  1156.     if (dec)
  1157.       {
  1158.     l = strlen (dec);
  1159.     c = cram (scr_cols - wid, thePort->status_font, dec, l, "[...]");
  1160.     *pos++ = '[';
  1161.     if (c < l)
  1162.       {
  1163.         if (c)
  1164.           bcopy (dec, pos, c);
  1165.         bcopy ("...]", pos, 4);
  1166.         pos += c + 4;
  1167.       }
  1168.     else
  1169.       {
  1170.         if (c)
  1171.           bcopy (dec, pos, c);
  1172.         pos += c;
  1173.         *pos++ = ']';
  1174.       }
  1175.       }
  1176.     
  1177.     *pos++ = '\0';
  1178.     set_status (assembled);
  1179.     draw_status ();
  1180.     free (assembled);
  1181.   }
  1182. }
  1183.  
  1184.  
  1185. #ifdef __STDC__
  1186. static int
  1187. xio_get_chr (char *prompt)
  1188. #else
  1189. static int
  1190. xio_get_chr (prompt)
  1191.      char *prompt;
  1192. #endif
  1193. {
  1194.   int len = strlen (prompt);
  1195.   set_input (prompt, len, len);
  1196.   topclear = 2;
  1197.   draw_input ();
  1198.   return io_getch ();
  1199. }
  1200.  
  1201.  
  1202. /*
  1203.  * Multi-line informational messages to the user:
  1204.  */
  1205.  
  1206. /* old: */
  1207. struct text_line
  1208. {
  1209.   struct text_line *next;
  1210.   int nchars;
  1211.   int standout;
  1212.   char line[TAIL_ARRAY];
  1213. };
  1214. static int text_damaged = 0;
  1215. static struct text_line *text_lines = 0;
  1216. extern int auto_recalc;
  1217.  
  1218.  
  1219. /****************************************************************
  1220.  * Low level support for the cell windows.
  1221.  ****************************************************************/
  1222.  
  1223. /* Every cell has an associated font name.  This is a cache mapping
  1224.  * font names and scales to graphics contexts.
  1225.  */
  1226.  
  1227. struct cell_gc
  1228. {
  1229.   struct cell_gc *next;
  1230.   struct cell_gc *prev;
  1231.   Xport port;
  1232.   GC gc;
  1233.   char *font_name;
  1234.   double scale;
  1235.   XFontStruct *font;
  1236.   int clipped_to;
  1237.   int cursor:1;
  1238. };
  1239.  
  1240. /* The cell_gc cache is only valid for a specific size default font.  If the
  1241.  * defualt font size changes, then the cache must be flushed.
  1242.  */
  1243. static int cell_gc_basis = 12;
  1244.  
  1245.  
  1246. /* Individual cache entries are also validated by the clipping set for their
  1247.  * gc.  To the rest of the system, it appears that there is one clipping region
  1248.  * for all cell_gc's.
  1249.  */
  1250. static int clipcnt = 0;
  1251. static int cliprectc = 0;
  1252. static int cliprect_alloc = 0;
  1253. static XRectangle *cliprectv = 0;
  1254.  
  1255. #define GC_CACHE_SIZE    10
  1256. static struct cell_gc *cell_gc_cache = 0;
  1257.  
  1258.  
  1259. /* This takes the full name of an X11 font, and returns its point size (in
  1260.  * tenths of a point.  If the string is not a valid font name, 0 is returned.
  1261.  */
  1262.  
  1263. #ifdef __STDC__
  1264. static int 
  1265. name_to_ps (char *xfont)
  1266. #else
  1267. static int 
  1268. name_to_ps (xfont)
  1269.      char *xfont;
  1270. #endif
  1271. {
  1272.   while (*xfont)
  1273.     if (*xfont == '-')
  1274.       {
  1275.     ++xfont;
  1276.     if (*xfont == '-')    /* look for -- */
  1277.       {
  1278.         ++xfont;
  1279.         break;
  1280.       }
  1281.       }
  1282.     else
  1283.       ++xfont;
  1284.   if (!*xfont)
  1285.     return 0;
  1286.   while (isdigit (*xfont++));
  1287.   --xfont;
  1288.   if (!*xfont++ == '-')
  1289.     return 0;
  1290.   return atoi (xfont);
  1291. }
  1292.  
  1293.  
  1294. #define ABS(A) ((A) < 0 ? -(A) : (A))
  1295.  
  1296. #ifdef __STDC__
  1297. static struct cell_gc *
  1298. cell_gc (Xport port, struct font_memo *font_passed, int cursor)
  1299. #else
  1300. static struct cell_gc *
  1301. cell_gc (port, font_passed, cursor)
  1302.      Xport port;
  1303.      struct font_memo *font_passed;
  1304.      int cursor;
  1305. #endif
  1306. {
  1307.   struct font_memo *font =
  1308.     (font_passed ? font_passed : default_font());
  1309.   char *font_name = font->names->x_name;
  1310.   double scale = font->scale;
  1311.   struct cell_gc *c = cell_gc_cache;
  1312.   if (cell_gc_basis != cell_font_point_size)
  1313.     {
  1314.       do
  1315.     {
  1316.       if (c->font_name)
  1317.         {
  1318.           XFreeFont (c->port->dpy, c->font);
  1319.           free (c->font_name);
  1320.         }
  1321.       c->font_name = 0;
  1322.       c->port = 0;
  1323.       c->font = 0;
  1324.       c = c->next;
  1325.     }
  1326.       while (c != cell_gc_cache);
  1327.       cell_gc_basis = cell_font_point_size;
  1328.     }
  1329.   else
  1330.     {
  1331.       do
  1332.     {
  1333.       if ((c->scale == scale)
  1334.           && port == c->port
  1335.           && c->font_name && !strcmp (font_name, c->font_name))
  1336.         {
  1337.           if (cell_gc_cache == c)
  1338.         cell_gc_cache = cell_gc_cache->next;
  1339.           c->next->prev = c->prev;
  1340.           c->prev->next = c->next;
  1341.           c->next = cell_gc_cache;
  1342.           c->prev = cell_gc_cache->prev;
  1343.           c->prev->next = c;
  1344.           c->next->prev = c;
  1345.           cell_gc_cache = c;
  1346.           goto check_clipping;
  1347.         }
  1348.       c = c->next;
  1349.     }
  1350.       while (c != cell_gc_cache);
  1351.     }
  1352.   
  1353.   c = c->prev;
  1354.   cell_gc_cache = c;
  1355.   if (c->font_name)
  1356.     {
  1357.       XFreeFont (c->port->dpy, c->font);
  1358.       free (c->font_name);
  1359.     }
  1360.   c->port = port;
  1361.   c->scale = scale;
  1362.   {
  1363.     char **fontv;
  1364.     int fontc;
  1365.     fontv = XListFonts (port->dpy, font_name, 1024, &fontc);
  1366.     if (fontv)
  1367.       {
  1368.     int x, best;
  1369.     int ideal_size = rint (scale * (double) cell_font_point_size * 10.);
  1370.     int best_dist;
  1371.     best = 0;
  1372.     best_dist = ideal_size - name_to_ps (fontv[0]);
  1373.     for (x = 1; x < fontc; ++x)
  1374.       {
  1375.         int ps = name_to_ps (fontv[x]);
  1376.         int tdist = ideal_size - ps;
  1377.         if (ABS (tdist) < ABS (best_dist)
  1378.         || ((ABS (tdist) == ABS (best_dist)) && (tdist > best_dist)))
  1379.           {
  1380.         best_dist = tdist;
  1381.         best = x;
  1382.           }
  1383.       }
  1384.     c->font = XLoadQueryFont (port->dpy, fontv[best]);
  1385.     XFreeFontNames (fontv);
  1386.       }
  1387.     else
  1388.       c->font = 0;
  1389.   }
  1390.   if (c->font)
  1391.     c->font_name = (char *) ck_savestr (font_name);
  1392.   else
  1393.     {
  1394.       c->font = XLoadQueryFont (port->dpy, cell_font_name);
  1395.       if (c->font)
  1396.     c->font_name = ck_savestr (cell_font_name);
  1397.       else
  1398.     {
  1399.       c->font = XLoadQueryFont (port->dpy, emergency_font_name);
  1400.       if (c->font)
  1401.         c->font_name = ck_savestr (emergency_font_name);
  1402.       else
  1403.         panic ("Unable to load even the emergency font.");
  1404.     }
  1405.     }
  1406.   
  1407.   {
  1408.     XGCValues v;
  1409.     v.font = c->font->fid;
  1410.     XChangeGC (port->dpy, c->gc, GCFont, &v);
  1411.   }
  1412.   
  1413.  check_clipping:
  1414.   
  1415.   if (clipcnt != c->clipped_to)
  1416.     {
  1417.       XSetClipRectangles (port->dpy, c->gc, 0, 0, cliprectv, cliprectc, Unsorted);
  1418.       c->clipped_to = clipcnt;
  1419.     }
  1420.   
  1421.   {
  1422.     XGCValues v;
  1423.     v.foreground = cursor ? port->bg_color_pixel : port->fg_color_pixel;
  1424.     v.background = cursor ? port->fg_color_pixel : port->bg_color_pixel;
  1425.     XChangeGC (port->dpy, c->gc, GCForeground | GCBackground, &v);
  1426.     c->cursor = cursor;
  1427.   }
  1428.   return c;
  1429. }
  1430.  
  1431.  
  1432.  
  1433. /* This is the data for an oleo window, displayed under X. */
  1434.  
  1435. enum kinds_of_layout_needed
  1436. {
  1437.   damaged_display = 1,
  1438.   new_display = 2
  1439. };
  1440.  
  1441. struct x_window
  1442. {
  1443.   struct x_window *next;
  1444.   struct window *win;
  1445.   struct display display;
  1446.   int layout_needed;
  1447.   int label_damage;
  1448.   Xport port;
  1449. };
  1450.  
  1451.  
  1452.  
  1453. #ifdef __STDC__
  1454. static void
  1455. collect_clipping (xx_IntRectangle rect)
  1456. #else
  1457. static void
  1458. collect_clipping (rect)
  1459.      xx_IntRectangle rect;
  1460. #endif
  1461. {
  1462.   if (cliprectc == cliprect_alloc)
  1463.     {
  1464.       cliprect_alloc = cliprect_alloc ? cliprect_alloc * 2 : 16;
  1465.       cliprectv =
  1466.     ((XRectangle *)
  1467.      ck_remalloc (cliprectv,
  1468.               cliprect_alloc * sizeof (XRectangle)));
  1469.     }
  1470.   cliprectv[cliprectc].x = rect->x;
  1471.   cliprectv[cliprectc].y = rect->y;
  1472.   cliprectv[cliprectc].width = rect->w;
  1473.   cliprectv[cliprectc].height = rect->h;
  1474.   ++cliprectc;
  1475. }
  1476.  
  1477. #ifdef __STDC__
  1478. static void 
  1479. clip_to_intrectangle (struct x_window * xwin, xx_IntRectangle rect)
  1480. #else
  1481. static void 
  1482. clip_to_intrectangle (xwin, rect)
  1483.      struct x_window * xwin;
  1484.      xx_IntRectangle rect;
  1485. #endif
  1486. {
  1487.   struct window * win = xwin->win;
  1488.   int x_ceil = win->win_over + win->numc;
  1489.   int y_ceil = win->win_down + win->numr;
  1490.  
  1491.   if (rect->w + rect->x >= x_ceil)
  1492.     {
  1493.       rect->w = x_ceil - rect->x;
  1494.     }
  1495.   if (rect->h + rect->y >= y_ceil)
  1496.     {
  1497.       rect->h = y_ceil - rect->y;
  1498.     }
  1499.   cliprectc = 0;
  1500.   collect_clipping (rect);
  1501.   ++clipcnt;
  1502. }
  1503.  
  1504.  
  1505. #ifdef __STDC__
  1506. static void 
  1507. place_text (xx_IntRectangle out, struct display *disp, struct cell_display *cd, XFontStruct *font, char *string)
  1508. #else
  1509. static void 
  1510. place_text (out, disp, cd, font, string)
  1511.      xx_IntRectangle out;
  1512.      struct display *disp;
  1513.      struct cell_display *cd;
  1514.      XFontStruct *font;
  1515.      char *string;
  1516. #endif
  1517. {
  1518.   int *widths = disp->widths;
  1519.   int *heights = disp->heights;
  1520.   int *colx = disp->colx;
  1521.   int *rowy = disp->rowy;
  1522.   struct rng *range = &disp->range;
  1523.   int hout = font->ascent + font->descent;
  1524.   int wout = XTextWidth (font, string, strlen (string));
  1525.   int ci = cd->c - range->lc;
  1526.   int ri = cd->r - range->lr;
  1527.   int yout = rowy[ri] + heights[ri] - (font->ascent + font->descent);
  1528.   int xout;
  1529.   switch (cd->justification)
  1530.     {
  1531.     default:
  1532.     case JST_LFT:
  1533.       xout = colx[ci];
  1534.       break;
  1535.     case JST_RGT:
  1536.       xout = colx[ci] + widths[ci] - 1 - wout;
  1537.       break;
  1538.     case JST_CNT:
  1539.       xout = colx[ci] + (widths[ci] - wout) / 2;
  1540.       break;
  1541.     }
  1542.   xx_IRinit (out, xout, yout, wout, hout);
  1543. }
  1544.  
  1545.  
  1546.  
  1547. #ifdef __STDC__
  1548. static void
  1549. x_metric (struct cell_display *cd, struct display *disp)
  1550. #else
  1551. static void
  1552. x_metric (cd, disp)
  1553.      struct cell_display *cd;
  1554.      struct display *disp;
  1555. #endif
  1556. {
  1557.   struct x_window *xw = (struct x_window *) disp->vdata;
  1558.   Xport port = xw->port;
  1559.   if (!cd->unclipped)
  1560.     xx_IRinit (&cd->goal, 0, 0, 0, 0);
  1561.   else
  1562.     {
  1563.       struct cell_gc *cgc = cell_gc (port, cd->font, 0);
  1564.       place_text (&cd->goal, disp, cd, cgc->font, cd->unclipped);
  1565.     }
  1566. }
  1567.  
  1568.  
  1569.  
  1570. #ifdef __STDC__
  1571. static struct x_window *
  1572. x_win (Xport port, struct window *win, int rebuild)
  1573. #else
  1574. static struct x_window *
  1575. x_win (port, win, rebuild)
  1576.      Xport port;
  1577.      struct window *win;
  1578.      int rebuild;
  1579. #endif
  1580. {
  1581.   struct x_window *xw;
  1582.   
  1583.   for (xw = port->xwins; xw && xw->win != win; xw = xw->next);
  1584.   
  1585.   if (xw && !rebuild)
  1586.     return xw;
  1587.   
  1588.   if (xw)
  1589.     {
  1590.       free_display (&xw->display);
  1591.     }
  1592.   else
  1593.     {
  1594.       xw = (struct x_window *) ck_malloc (sizeof (*xw));
  1595.       xw->next = port->xwins;
  1596.       port->xwins = xw;
  1597.       xw->port = port;
  1598.     }
  1599.   xw->win = win;
  1600.   build_display (&xw->display, &win->screen, x_metric, xw);
  1601.   xw->label_damage = 1;
  1602.   xw->layout_needed = new_display;
  1603.   port->redisp_needed = 1;
  1604.   return xw;
  1605. }
  1606.  
  1607. #ifdef __STDC__
  1608. static void
  1609. flush_x_windows (Xport port)
  1610. #else
  1611. static void
  1612. flush_x_windows (port)
  1613.      Xport port;
  1614. #endif
  1615. {
  1616.   while (port->xwins)
  1617.     {
  1618.       struct x_window * xw = port->xwins;
  1619.       free_display (&xw->display);
  1620.       port->xwins = xw->next;
  1621.       free (xw);
  1622.       port->redisp_needed = 1;
  1623.     }
  1624. }
  1625.  
  1626.  
  1627.  
  1628.  
  1629. #ifdef __STDC__
  1630. static void
  1631. record_damage (Xport port, int x, int y, int w, int h)
  1632. #else
  1633. static void
  1634. record_damage (port, x, y, w, h)
  1635.      Xport port;
  1636.      int x;
  1637.      int y;
  1638.      int w;
  1639.      int h;
  1640. #endif
  1641. {
  1642.   struct x_window *xwin = port->xwins;
  1643.   
  1644.   if (port->input_view.current_info)
  1645.     {
  1646.       port->input_view.info_redraw_needed = 1;
  1647.       return;
  1648.     }
  1649.  
  1650.   if (text_lines)
  1651.     {
  1652.       text_damaged = 1;
  1653.       return;
  1654.     }
  1655.   
  1656.   while (xwin)
  1657.     {
  1658.       struct window *win = xwin->win;
  1659.       record_display_damage (&xwin->display,
  1660.                  x - win->win_over,
  1661.                  y - win->win_down,
  1662.                  w, h);
  1663.       port->redisp_needed = 1;
  1664.       if (   (   (x + w >= win->win_over - win_label_cols(win, win->screen.hr))
  1665.           && (x <= win->win_over)
  1666.           && (y + h >= win->win_down - win_label_rows(win))
  1667.           && (y <= win->win_down + display_height(&xwin->display)))
  1668.       || (   (y + h >= win->win_down - win_label_rows(win))
  1669.           && (y <= win->win_down)
  1670.           && (x + w >= win->win_over - win_label_cols(win, win->screen.hr))
  1671.           && (x <= win->win_over + display_width(&xwin->display))))
  1672.     xwin->label_damage = 1;
  1673.       xwin = xwin->next;
  1674.     }
  1675.  
  1676.   if (((input + input_rows) >= y) && (input <= y + h))
  1677.     port->input_view.redraw_needed = FULL_REDRAW;
  1678. }
  1679.  
  1680.  
  1681.  
  1682. #ifdef __STDC__
  1683. static void
  1684. xio_pr_cell_win (struct window *win, CELLREF r, CELLREF c, CELL *cp)
  1685. #else
  1686. static void
  1687. xio_pr_cell_win (win, r, c, cp)
  1688.      struct window *win;
  1689.      CELLREF r;
  1690.      CELLREF c;
  1691.      CELL *cp;
  1692. #endif
  1693. {
  1694.   struct x_window *xwin = x_win (thePort, win, 0);
  1695.   struct display *disp = &xwin->display;
  1696.   
  1697.   if (pr_display_cell (disp, r, c, cp))
  1698.     {
  1699.       thePort->redisp_needed = 1;
  1700.       if (!xwin->layout_needed)
  1701.     xwin->layout_needed = damaged_display;
  1702.     }
  1703. }
  1704.  
  1705.  
  1706. #ifdef __STDC__
  1707. static void
  1708. xio_repaint_win (struct window *win)
  1709. #else
  1710. static void
  1711. xio_repaint_win (win)
  1712.      struct window *win;
  1713. #endif
  1714. {
  1715.   x_win (thePort, win, 1);
  1716.   XFillRectangle (thePort->dpy, thePort->window, thePort->neutral_gc,
  1717.           win->win_over, win->win_down, win->numc, win->numr);
  1718.   record_damage (thePort, win->win_over, win->win_down, win->numc, win->numr);
  1719. }
  1720.  
  1721.  
  1722.  
  1723. #ifdef __STDC__
  1724. static void
  1725. xio_repaint (void)
  1726. #else
  1727. static void
  1728. xio_repaint ()
  1729. #endif
  1730. {
  1731.   struct window *win;
  1732.   if (thePort->input_view.current_info)
  1733.     {
  1734.       thePort->input_view.info_redraw_needed = 1;
  1735.       return;
  1736.     }
  1737.   flush_x_windows (thePort);
  1738.   for (win = wins; win < &wins[nwin]; win++)
  1739.     xio_repaint_win (win);
  1740. }
  1741.  
  1742.  
  1743. #ifdef __STDC__
  1744. static void
  1745. draw_cell (struct x_window *xwin, struct cell_display *cd_passed, int cursor)
  1746. #else
  1747. static void
  1748. draw_cell (xwin, cd_passed, cursor)
  1749.      struct x_window *xwin;
  1750.      struct cell_display *cd_passed;
  1751.      int cursor;
  1752.      
  1753. #endif
  1754. {
  1755.   struct cell_display *cd = cd_passed->used_by;
  1756.   Xport port = xwin->port;
  1757.   struct window *win = xwin->win;
  1758.   int ov = win->win_over;
  1759.   int dn = win->win_down;
  1760.   CELLREF r = cd->r;
  1761.   CELLREF c = cd->c;
  1762.   struct display *disp = &xwin->display;
  1763.   int *rowy = disp->rowy;
  1764.   int *colx = disp->colx;
  1765.   int *widths = disp->widths;
  1766.   int *heights = disp->heights;
  1767.   struct cell_gc *cgc;
  1768.   int ri = r - disp->range.lr;
  1769.   int ci = c - disp->range.lc;
  1770.   
  1771.   if (!(widths[ci] && heights[ri]))
  1772.     return;
  1773.   
  1774.   if (!cd->unclipped)
  1775.     {
  1776.       cgc = cell_gc (port, default_font(), !cursor);
  1777.       XFillRectangle (port->dpy, port->window, cgc->gc,
  1778.               colx[ci] + ov, rowy[ri] + dn,
  1779.               widths[ci], heights[ri]);
  1780.       return;
  1781.     }
  1782.   
  1783.   cgc = cell_gc (port, cd->font, cursor);
  1784.   {
  1785.     int isclipped;
  1786.     char *str;
  1787.     struct xx_sIntRectangle *strbox;
  1788.     
  1789.     isclipped = !xx_IRencloses_width (&cd->layout, &cd->goal);
  1790.     if (!isclipped)
  1791.       {
  1792.     str = cd->unclipped;
  1793.     strbox = &cd->goal;
  1794.       }
  1795.     else
  1796.       {
  1797.     if (!cd->clipped)
  1798.       {
  1799.         int chr_scale = XTextWidth (cgc->font, "8", 1);
  1800.         int w_avail = xx_IRw (&cd->layout) / chr_scale;
  1801.         int cell_wid = widths[ci] / chr_scale;
  1802.         CELL *cp = find_cell (r, c);
  1803.         cd->clipped =
  1804.           ck_savestr (adjust_prc (cd->unclipped, cp, w_avail, cell_wid,
  1805.                       cd->justification));
  1806.         place_text (&cd->clip, disp, cd, cgc->font, cd->clipped);
  1807.       }
  1808.     str = cd->clipped;
  1809.     strbox = &cd->clip;
  1810.       }
  1811.     XDrawImageString (port->dpy, port->window, cgc->gc,
  1812.               strbox->x + ov, strbox->y + cgc->font->ascent + dn,
  1813.               str, strlen (str));
  1814.     {
  1815.       struct xx_sIntRectangle tofill[4];
  1816.       int fillc;
  1817.       
  1818.       fillc = xx_IRsubtract (tofill, &cd->layout, strbox);
  1819.       {
  1820.     XGCValues v;
  1821.     v.foreground = cursor ? port->fg_color_pixel : port->bg_color_pixel;
  1822.     v.background = cursor ? port->bg_color_pixel : port->fg_color_pixel;
  1823.     XChangeGC (port->dpy, cgc->gc, GCForeground | GCBackground, &v);
  1824.     cgc->cursor = !cursor;
  1825.       }
  1826.       while (fillc--)
  1827.     XFillRectangle (port->dpy, port->window, cgc->gc,
  1828.             tofill[fillc].x + ov, tofill[fillc].y + dn,
  1829.             tofill[fillc].w, tofill[fillc].h);
  1830.     }
  1831.   }
  1832. }
  1833.  
  1834.  
  1835. /* Cell values */
  1836.  
  1837. #ifdef __STDC__
  1838. static void
  1839. set_cursor (int on)
  1840. #else
  1841. static void
  1842. set_cursor (on)
  1843.      int on;
  1844. #endif
  1845. {
  1846.   struct x_window *xwin = x_win (thePort, cwin, 0);
  1847.   struct display *disp = &xwin->display;
  1848.   int *rowy = disp->rowy;
  1849.   int *colx = disp->colx;
  1850.   int *widths = disp->widths;
  1851.   int *heights = disp->heights;
  1852.   int ri = curow - disp->range.lr;
  1853.   int ci = cucol - disp->range.lc;
  1854.   int ov = xwin->win->win_over;
  1855.   int dn = xwin->win->win_down;
  1856.   struct cell_display *cd = cell_display_of (disp, curow, cucol);
  1857.   struct xx_sIntRectangle clip;
  1858.  
  1859.   /* The cursor might not even be visible.  Though commands should never leave
  1860.    * the user in such a state, it can happen in several ways transiently.
  1861.    */
  1862.   if (!cd)
  1863.     return;
  1864.  
  1865.   thePort->cursor_visible = on;
  1866.   
  1867.   if (xwin->layout_needed == new_display)
  1868.     return;
  1869.   
  1870.   if (cd->used_by == cd)
  1871.     {
  1872.       clip = cd->layout;
  1873.       clip.x += ov;
  1874.       clip.y += dn;
  1875.     }
  1876.   else
  1877.     xx_IRinit (&clip,
  1878.            colx[ci] + ov, rowy[ri] + dn,
  1879.            widths[ci], heights[ri]);
  1880.   clip_to_intrectangle (xwin, &clip);
  1881.   draw_cell (xwin, cd, on);
  1882. }
  1883.  
  1884.  
  1885. #ifdef __STDC__
  1886. static void
  1887. xio_hide_cell_cursor (void)
  1888. #else
  1889. static void
  1890. xio_hide_cell_cursor ()
  1891. #endif
  1892. {
  1893.   if (thePort->cursor_visible)
  1894.     set_cursor (0);
  1895. }
  1896.  
  1897. #ifdef __STDC__
  1898. static void
  1899. xio_display_cell_cursor (void)
  1900. #else
  1901. static void
  1902. xio_display_cell_cursor ()
  1903. #endif
  1904. {
  1905.   if (!thePort->cursor_visible)
  1906.     {
  1907.       if (   (curow < cwin->screen.lr)
  1908.       || (cucol < cwin->screen.lc)
  1909.       || (curow > cwin->screen.hr)
  1910.       || (cucol > cwin->screen.hc))
  1911.     io_recenter_cur_win ();
  1912.       set_cursor (1);
  1913.     }
  1914. }
  1915.  
  1916.  
  1917. static int xx[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
  1918.  
  1919.  
  1920. #ifdef __STDC__
  1921. static void
  1922. draw_labels (void)
  1923. #else
  1924. static void
  1925. draw_labels ()
  1926. #endif
  1927. {
  1928.   struct x_window *xwin;
  1929.   XRectangle rect;
  1930.   for (xwin = thePort->xwins; xwin; xwin = xwin->next)
  1931.     if (xwin->win->lh_wid && xwin->label_damage)
  1932.       {
  1933.     XGCValues gcv;
  1934.     struct window *win = xwin->win;
  1935.     int wid2 = win->lh_wid / 2;
  1936.     if (xx[0]) {
  1937.       XFillRectangle (thePort->dpy, thePort->window,
  1938.               thePort->label_standout_gc,
  1939.               win->win_over - win->lh_wid,
  1940.               win->win_down - label_rows,
  1941.               wid2, label_rows);
  1942.     };
  1943.     gcv.line_width = win->lh_wid;
  1944.     gcv.cap_style = CapRound;
  1945.     XChangeGC (thePort->dpy, thePort->label_gc,
  1946.            GCLineWidth | GCCapStyle, &gcv);
  1947.     if (xx[1]) {
  1948.       XDrawLine (thePort->dpy, thePort->window, thePort->label_gc,
  1949.              win->win_over - wid2,
  1950.              win->win_down - label_rows + wid2,
  1951.              win->win_over - wid2,
  1952.              win->win_down + win->numr - wid2);
  1953.       
  1954.     };
  1955.     gcv.cap_style = CapButt;
  1956.     XChangeGC (thePort->dpy, thePort->label_gc, GCCapStyle, &gcv);
  1957.     if (xx[2]) {
  1958.       XDrawLine (thePort->dpy, thePort->window, thePort->label_gc,
  1959.              win->win_over - wid2,
  1960.              win->win_down + wid2,
  1961.              win->win_over - wid2,
  1962.              win->win_down + win->numr);
  1963.     };
  1964.     
  1965.     if (xx[3]) {
  1966.       XFillRectangle (thePort->dpy, thePort->window, thePort->label_gc,
  1967.               win->win_over - wid2,
  1968.               win->win_down - label_rows,
  1969.               win->numc + wid2,
  1970.               label_rows);
  1971.     };
  1972.     
  1973.     rect.x = 0;
  1974.     rect.y = 0;
  1975.     rect.width = scr_cols;
  1976.     rect.height = scr_lines;
  1977.     XSetClipRectangles (thePort->dpy, thePort->label_standout_gc,
  1978.                 0, 0, &rect, 1, YXBanded);
  1979.     {
  1980.       char buf[100];
  1981.       CELLREF cr;
  1982.       int x;
  1983.       int len;
  1984.       
  1985.       sprintf (buf, "#%d", 1 + win - wins);
  1986.       for (x = len = 0; buf[x]; ++x)
  1987.         {
  1988.           int cwid = XTextWidth (thePort->label_font, buf, 1);
  1989.           if (cwid + len > wid2)
  1990.         break;
  1991.           len += cwid;
  1992.         }
  1993.       XDrawImageString (thePort->dpy, thePort->window,
  1994.                 thePort->label_standout_gc,
  1995.                 win->win_over - wid2,
  1996.                 win->win_down - thePort->label_font->descent,
  1997.                 buf, x);
  1998.       
  1999.       rect.x = win->win_over - win->lh_wid;
  2000.       rect.y = win->win_down;
  2001.       rect.width = win->lh_wid;
  2002.       rect.height = win->numr;
  2003.       XSetClipRectangles (thePort->dpy, thePort->label_standout_gc,
  2004.                   0, 0, &rect, 1, YXBanded);
  2005.       
  2006.       x = win->win_down + thePort->label_font->ascent;
  2007.       for (cr = win->screen.lr; cr <= win->screen.hr; ++cr)
  2008.         {
  2009.           int hgt = get_scaled_height (cr);
  2010.           if (hgt)
  2011.         {
  2012.           if (a0)
  2013.             sprintf (buf, "%d", cr);
  2014.           else
  2015.             sprintf (buf, "R%d", cr);
  2016.           XDrawImageString (thePort->dpy, thePort->window,
  2017.                     thePort->label_standout_gc,
  2018.                     win->win_over - win->lh_wid, x,
  2019.                     buf, strlen (buf));
  2020.           x += hgt;
  2021.         }
  2022.           if (cr == MAX_ROW)
  2023.         break;
  2024.         }
  2025.       rect.x = 0;
  2026.       rect.y = 0;
  2027.       rect.width = scr_cols;
  2028.       rect.height = scr_lines;
  2029.       XSetClipRectangles (thePort->dpy, thePort->label_standout_gc,
  2030.                   0, 0, &rect, 1, YXBanded);
  2031.       
  2032.       x = win->win_over;
  2033.       for (cr = win->screen.lc; cr <= win->screen.hc; ++cr)
  2034.         {
  2035.           int wid = get_scaled_width (cr);
  2036.           if (wid > win->numc)
  2037.         wid = win->numc;
  2038.           if (wid)
  2039.         {
  2040.           int txtwid;
  2041.           char *ptr;
  2042.           if (a0)
  2043.             ptr = col_to_str (cr);
  2044.           else
  2045.             {
  2046.               ptr = buf;
  2047.               sprintf (ptr, "C%u", cr);
  2048.             }
  2049.           txtwid = XTextWidth (thePort->label_font, ptr, strlen (ptr));
  2050.           if (txtwid > wid - thePort->label_font->max_bounds.width)
  2051.             {
  2052.               int txtlen =
  2053.             ((wid - thePort->label_font->max_bounds.width)
  2054.              / XTextWidth (thePort->label_font, "#", 1));
  2055.               txtwid = txtlen * XTextWidth (thePort->label_font,
  2056.                             "#", 1);
  2057.               buf[txtlen] = 0;
  2058.               while (txtlen)
  2059.             buf[txtlen--] = '#';
  2060.               ptr = buf;
  2061.             }
  2062.           XDrawImageString (thePort->dpy, thePort->window,
  2063.                     thePort->label_standout_gc,
  2064.                     x + (wid - txtwid) / 2,
  2065.                     (win->win_down
  2066.                      - thePort->label_font->descent),
  2067.                     ptr, strlen (ptr));
  2068.           x += wid;
  2069.         }
  2070.           if (cr == MAX_COL)
  2071.         break;
  2072.         }
  2073.     }
  2074.     xwin->label_damage = 0;
  2075.       }
  2076. }
  2077.  
  2078.  
  2079. /* Refresh the existing image. */
  2080.  
  2081.  
  2082. #ifdef __STDC__
  2083. static void
  2084. xio_redisp (void)
  2085. #else
  2086. static void
  2087. xio_redisp ()
  2088. #endif
  2089. {
  2090.   static int was_text = 0;
  2091.   if (thePort->input_view.current_info)
  2092.     {
  2093.       if (!was_text)
  2094.     thePort->input_view.redraw_needed = FULL_REDRAW;
  2095.  
  2096.       if (thePort->input_view.redraw_needed != NO_REDRAW)
  2097.     xio_redraw_input ();
  2098.  
  2099.       if (thePort->input_view.info_redraw_needed)
  2100.     {
  2101.       int ipos = thePort->input_view.info_pos;
  2102.       int top = ipos + (scr_lines - input_rows) / info_rows - 1;
  2103.       int ypos;
  2104.       XTextItem text;
  2105.  
  2106.       if (top >= thePort->input_view.current_info->len)
  2107.         top = thePort->input_view.current_info->len - 1;
  2108.  
  2109.       ypos = input_rows;
  2110.  
  2111.       text.font = thePort->text_line_font->fid;
  2112.       while (ipos <= top)
  2113.         {
  2114.           text.chars = thePort->input_view.current_info->text[ipos];
  2115.           text.nchars = strlen (text.chars);
  2116.           draw_text_item (thePort, 0, ypos, scr_cols, input_rows,
  2117.                   thePort->text_line_font, thePort->text_line_gc,
  2118.                   &text, 0);
  2119.           ypos += info_rows;
  2120.           ++ipos;
  2121.         }
  2122.       XFillRectangle (thePort->dpy, thePort->window,
  2123.               thePort->neutral_gc, 0, ypos,
  2124.               scr_cols, scr_lines - ypos - 1);
  2125.       thePort->input_view.redraw_needed = FULL_REDRAW;
  2126.       xio_redraw_input ();
  2127.       thePort->input_view.info_redraw_needed = 0;
  2128.       was_text = 1;
  2129.     }
  2130.     }
  2131.   else
  2132.     {
  2133.       struct x_window *xwin;
  2134.       if (was_text)
  2135.     {
  2136.       thePort->input_view.info_redraw_needed = 0;
  2137.       was_text = 0;
  2138.       io_repaint ();
  2139.     }
  2140.       else
  2141.     {
  2142.       struct rng * rng = &cwin->screen;
  2143.       if (   (curow > rng->hr)
  2144.           || (curow < rng->lr)
  2145.           || (cucol > rng->hc)
  2146.           || (cucol < rng->lc))
  2147.         io_recenter_cur_win ();
  2148.     }
  2149.       thePort->redisp_needed = 0;
  2150.       if (thePort->redisp_needed != NO_REDRAW)
  2151.     xio_redraw_input ();
  2152.       draw_status ();
  2153.       draw_labels ();
  2154.       for (xwin = thePort->xwins; xwin; xwin = xwin->next)
  2155.     {
  2156.       struct display *disp = &xwin->display;
  2157.       int ov = xwin->win->win_over;
  2158.       int dn = xwin->win->win_down;
  2159.       struct cell_display * cd;
  2160.       struct cell_display * cursor_cd = 0;
  2161.       int must_draw_cursor;
  2162.       
  2163.       if (xwin->layout_needed)
  2164.         {
  2165.           layout (disp);
  2166.           xwin->layout_needed = 0;
  2167.         }
  2168.       
  2169.       /* If the cursor cell has been damaged, 
  2170.        * it will be redrawn.  However, if the 
  2171.        * cursor cell is empty, then redrawing
  2172.        * some other cell might damage the cursor.
  2173.        * This watches for that condition and
  2174.        * redraws the cursor if it occurs.
  2175.        */
  2176.       must_draw_cursor = 0;
  2177.       if (thePort->cursor_visible
  2178.           && (xwin->win == cwin)
  2179.           && (curow >= disp->range.lr)
  2180.           && (curow <= disp->range.hr)
  2181.           && (cucol >= disp->range.lc)
  2182.           && (cucol <= disp->range.hc))
  2183.         {
  2184.           cursor_cd = cell_display_of (disp, curow, cucol);
  2185.           /* If the cursor cell is not empty, we never have
  2186.            * to explicitly redraw the cursor.
  2187.            */
  2188.           if (cursor_cd->used_by == cursor_cd)
  2189.         cursor_cd = 0;
  2190.         }
  2191.       
  2192.       cd = disp->damaged;
  2193.       while (cd != (struct cell_display *) disp)
  2194.         {
  2195.           struct xx_sIntRectangle clip;
  2196.           struct cell_display *owner = cd->used_by;
  2197.           clip = owner->layout;
  2198.           clip.x += ov;
  2199.           clip.y += dn;
  2200.           clip_to_intrectangle (xwin, &clip);
  2201.           if (cursor_cd && (cd->used_by == cursor_cd->used_by))
  2202.         must_draw_cursor = 1;
  2203.           draw_cell (xwin, owner,
  2204.              (thePort->cursor_visible
  2205.               && (xwin->win == cwin)
  2206.               && (owner->r == curow)
  2207.               && (owner->c == cucol)));
  2208.           {    
  2209.         struct cell_display *cdt = cd;
  2210.         cd = cd->next_damaged;
  2211.         cdt->next_damaged = 0;
  2212.           }
  2213.         }
  2214.       disp->damaged = (struct cell_display *) disp;
  2215.       if (must_draw_cursor)
  2216.         set_cursor (1);
  2217.     }
  2218.     }
  2219. }
  2220.  
  2221.  
  2222.  
  2223.  
  2224. #ifdef __STDC__
  2225. static XFontStruct *
  2226. reasonable_font (Xport port, char *name)
  2227. #else
  2228. static XFontStruct *
  2229. reasonable_font (port, name)
  2230.      Xport port;
  2231.      char *name;
  2232. #endif
  2233. {
  2234.   XFontStruct *f = XLoadQueryFont (port->dpy, name);
  2235.   
  2236.   if (!f)
  2237.     {
  2238.       printf("(warning) Font %s could not be loaded.\n", name);
  2239.       f = XLoadQueryFont (port->dpy, default_font_name);
  2240.       if (!f)
  2241.     {
  2242.       panic ("Default font %s could not be loaded.\n",
  2243.          default_font_name);
  2244.       exit(0);
  2245.     }
  2246.     }
  2247.   return f;
  2248. }
  2249.  
  2250. #ifdef __STDC__
  2251. extern void 
  2252. xio_open_display (void)
  2253. #else
  2254. extern void 
  2255. xio_open_display ()
  2256. #endif
  2257. {
  2258.   XGCValues gcv;
  2259.   XWMHints wmhints;
  2260.   
  2261.   thePort = (Xport) ck_malloc (sizeof (*thePort));
  2262.   thePort->cursor_visible = 1;
  2263.   thePort->redisp_needed = 1;
  2264.   thePort->xwins = 0;
  2265.   
  2266.   thePort->dpy = theDisplay;
  2267.  
  2268.   bzero (&thePort->input_view, sizeof (struct input_view));
  2269.   thePort->input_view.prompt_metric = x_input_metric;
  2270.   thePort->input_view.input_metric = x_input_metric;
  2271.   
  2272.   thePort->screen = DefaultScreen (thePort->dpy);
  2273.   thePort->color_map = DefaultColormap (thePort->dpy, thePort->screen);
  2274.   
  2275.   if (default_fg_color_name && 
  2276.       XParseColor (thePort->dpy, thePort->color_map, default_fg_color_name, &thePort->fg_color) &&
  2277.       XAllocColor(thePort->dpy, thePort->color_map, &thePort->fg_color))
  2278.     thePort->fg_color_pixel = thePort->fg_color.pixel;
  2279.   else
  2280.     if (default_fg_color_name && !stricmp (default_fg_color_name, "black"))
  2281.       thePort->fg_color_pixel = BlackPixel (thePort->dpy, thePort->screen);
  2282.     else
  2283.       if (default_fg_color_name && !stricmp (default_fg_color_name, "white"))
  2284.     thePort->fg_color_pixel = WhitePixel (thePort->dpy, thePort->screen);
  2285.   
  2286.   if (default_bg_color_name && 
  2287.       XParseColor (thePort->dpy, thePort->color_map, default_bg_color_name, &thePort->bg_color) &&
  2288.       XAllocColor(thePort->dpy, thePort->color_map, &thePort->bg_color))
  2289.     thePort->bg_color_pixel = thePort->bg_color.pixel;
  2290.   else
  2291.     if (default_bg_color_name && !stricmp (default_bg_color_name, "black"))
  2292.       thePort->bg_color_pixel = BlackPixel (thePort->dpy, thePort->screen);
  2293.     else
  2294.       if (default_bg_color_name && !stricmp (default_bg_color_name, "white"))
  2295.     thePort->fg_color_pixel = WhitePixel (thePort->dpy, thePort->screen);
  2296.   
  2297.   thePort->window =
  2298.     XCreateSimpleWindow (thePort->dpy, DefaultRootWindow (thePort->dpy),
  2299.              geom_x, geom_y, geom_w, geom_h,
  2300.              1, thePort->fg_color_pixel, thePort->bg_color_pixel);
  2301.   XStoreName (thePort->dpy, thePort->window, oleo_version_string);
  2302.   wmhints.flags = InputHint;
  2303.   wmhints.input = True;
  2304.   XSetWMHints(thePort->dpy, thePort->window, &wmhints);
  2305.  
  2306.   thePort->wm_delete_window = XInternAtom(thePort->dpy, "WM_DELETE_WINDOW", False);
  2307.   (void) XSetWMProtocols( thePort->dpy, thePort->window, &thePort->wm_delete_window, 1);
  2308.   
  2309.   gcv.foreground = thePort->bg_color_pixel;
  2310.   gcv.background = thePort->bg_color_pixel;
  2311.   thePort->neutral_gc =
  2312.     XCreateGC (thePort->dpy, DefaultRootWindow (thePort->dpy),
  2313.            (GCForeground | GCBackground), &gcv);
  2314.   
  2315.   gcv.foreground = thePort->fg_color_pixel;
  2316.   gcv.background = thePort->bg_color_pixel;
  2317.   thePort->normal_gc =
  2318.     XCreateGC (thePort->dpy, DefaultRootWindow (thePort->dpy),
  2319.            (GCForeground | GCBackground), &gcv);
  2320.   
  2321.   gcv.foreground = thePort->bg_color_pixel;
  2322.   gcv.background = thePort->fg_color_pixel;
  2323.   thePort->standout_gc =
  2324.     XCreateGC (thePort->dpy, DefaultRootWindow (thePort->dpy),
  2325.            (GCForeground | GCBackground), &gcv);
  2326.   
  2327.   thePort->input_font = reasonable_font (thePort, input_font_name);
  2328.   gcv.font = thePort->input_font->fid;
  2329.   gcv.foreground = thePort->fg_color_pixel;
  2330.   gcv.background = thePort->bg_color_pixel;
  2331.   thePort->input_gc =
  2332.     XCreateGC (thePort->dpy, DefaultRootWindow (thePort->dpy),
  2333.            (GCForeground | GCBackground | GCFont), &gcv);
  2334.   
  2335.   gcv.foreground = thePort->bg_color_pixel;
  2336.   gcv.background = thePort->fg_color_pixel;
  2337.   thePort->standout_input_gc =
  2338.     XCreateGC (thePort->dpy, DefaultRootWindow (thePort->dpy),
  2339.            (GCForeground | GCBackground | GCFont), &gcv);
  2340.   
  2341.   gcv.foreground = thePort->fg_color_pixel;
  2342.   gcv.background = thePort->bg_color_pixel;
  2343.   thePort->status_font = reasonable_font (thePort, status_font_name);
  2344.   gcv.font = thePort->status_font->fid;
  2345.   thePort->status_gc =
  2346.     XCreateGC (thePort->dpy, DefaultRootWindow (thePort->dpy),
  2347.            (GCForeground | GCBackground | GCFont), &gcv);
  2348.   
  2349.   thePort->label_font = reasonable_font (thePort, label_font_name);
  2350.   gcv.font = thePort->label_font->fid;
  2351.   gcv.cap_style = CapRound;
  2352.   thePort->label_gc =
  2353.     XCreateGC (thePort->dpy, DefaultRootWindow (thePort->dpy),
  2354.            (GCForeground | GCBackground | GCFont | GCCapStyle), &gcv);
  2355.   
  2356.   gcv.background = thePort->fg_color_pixel;
  2357.   gcv.foreground = thePort->bg_color_pixel;
  2358.   thePort->label_standout_gc =
  2359.     XCreateGC (thePort->dpy, DefaultRootWindow (thePort->dpy),
  2360.            (GCForeground | GCBackground | GCFont | GCCapStyle), &gcv);
  2361.   
  2362.   gcv.background = thePort->bg_color_pixel;
  2363.   gcv.foreground = thePort->fg_color_pixel;
  2364.   thePort->text_line_font = reasonable_font (thePort, text_line_font_name);
  2365.   gcv.font = thePort->text_line_font->fid;
  2366.   thePort->text_line_gc =
  2367.     XCreateGC (thePort->dpy, DefaultRootWindow (thePort->dpy),
  2368.            (GCForeground | GCBackground | GCFont), &gcv);
  2369.  
  2370.   info_rows = (thePort->text_line_font->max_bounds.ascent
  2371.            + thePort->text_line_font->max_bounds.descent);
  2372.   
  2373.   gcv.background = thePort->fg_color_pixel;
  2374.   gcv.foreground = thePort->bg_color_pixel;
  2375.   thePort->text_line_standout_gc =
  2376.     XCreateGC (thePort->dpy, DefaultRootWindow (thePort->dpy),
  2377.            (GCForeground | GCBackground | GCFont), &gcv);
  2378.   
  2379.   gcv.background = thePort->fg_color_pixel;
  2380.   gcv.foreground = thePort->bg_color_pixel;
  2381.   thePort->text_line_standout_gc =
  2382.     XCreateGC (thePort->dpy, DefaultRootWindow (thePort->dpy),
  2383.            (GCForeground | GCBackground | GCFont), &gcv);
  2384.   
  2385.   gcv.background = thePort->bg_color_pixel;
  2386.   gcv.foreground = thePort->fg_color_pixel;
  2387.   
  2388.   {
  2389.     int x;
  2390.     for (x = 0; x < GC_CACHE_SIZE; ++x)
  2391.       {
  2392.     struct cell_gc *cg =
  2393.       (struct cell_gc *) ck_malloc (sizeof (struct cell_gc));
  2394.     cg->font_name = 0;
  2395.     cg->font = 0;
  2396.     cg->clipped_to = 0;
  2397.     cg->cursor = 0;
  2398.     cg->gc = XCreateGC (thePort->dpy, DefaultRootWindow (thePort->dpy),
  2399.                 (GCForeground | GCBackground), &gcv);
  2400.     if (!cell_gc_cache)
  2401.       {
  2402.         cg->next = cg;
  2403.         cg->prev = cg;
  2404.       }
  2405.     else
  2406.       {
  2407.         cg->next = cell_gc_cache;
  2408.         cg->prev = cg->next->prev;
  2409.         cg->next->prev = cg;
  2410.         cg->prev->next = cg;
  2411.       }
  2412.     cell_gc_cache = cg;
  2413.       }
  2414.   }
  2415.   
  2416.   XSelectInput (thePort->dpy, thePort->window,
  2417.         (ExposureMask | StructureNotifyMask | KeyPressMask
  2418.          | ButtonPressMask));
  2419.   
  2420.   io_init_windows (geom_h, geom_w, 1, 2,
  2421.            thePort->input_font->ascent + thePort->input_font->descent,
  2422.            (thePort->status_font->ascent
  2423.             + thePort->status_font->descent),
  2424.            thePort->label_font->ascent + thePort->label_font->descent,
  2425.            thePort->label_font->max_bounds.width);
  2426.   x11_opened = 1;
  2427.   
  2428.   {
  2429.     struct cell_gc *cgc = cell_gc (thePort, default_font(), 0);
  2430.     height_scale = cgc->font->ascent + cgc->font->descent;
  2431.     width_scale = XTextWidth (cgc->font, "M", 1);
  2432.   }
  2433.  
  2434.   /* Setup the arrow keys.  Modifiers effect the last character
  2435.    * of the translation.
  2436.    */
  2437.   {
  2438.     static KeySym meta_shift_ctrl[]
  2439.       = {Mod1MapIndex, ShiftMapIndex, ControlMapIndex };
  2440. #define shift_ctrl &meta_shift_ctrl[1]
  2441. #define ctrl  &meta_shift_ctrl[2]
  2442.     static KeySym meta_shift[] = {Mod1MapIndex, ShiftMapIndex};
  2443. #define shift &meta_shift[1]
  2444.     static KeySym ctrl_meta[] = {ControlMapIndex, Mod1MapIndex};
  2445. #define meta &ctrl_meta[1]
  2446.  
  2447.     static KeySym * mod_combos [] =
  2448.       {
  2449.     0,
  2450.     ctrl, shift, meta,
  2451.     shift_ctrl, ctrl_meta, meta_shift,
  2452.     meta_shift_ctrl
  2453.       };
  2454.     static char meta_modp [] = { 0, 0, 0, 1, 0, 1, 1, 1 };
  2455.     static char base_char [] =
  2456.       {
  2457.     'A', '\001', 'a', 'A',
  2458.     '\001', '\001', 'a', '\001'
  2459.       };
  2460.     /* In ansi order: */
  2461.     static KeySym arrows[] = {XK_Up, XK_Down, XK_Right, XK_Left};
  2462.     int arrow;
  2463.  
  2464.     for (arrow = 0; arrow < 4; ++arrow)
  2465.       {
  2466.     int mod;
  2467.     for (mod = 0; mod < 8; ++mod)
  2468.       {
  2469.         char string[10];
  2470.         sprintf (string, "\033[%s%c",
  2471.              meta_modp[mod] ? "\033" : "",
  2472.              base_char[mod] + arrow);
  2473.         XRebindKeysym (thePort->dpy, arrows[arrow],
  2474.                mod_combos[mod], (mod + 2) / 3,
  2475.                string, strlen(string));
  2476.       }
  2477.       }
  2478.   }
  2479.   
  2480.   XMapWindow (thePort->dpy, thePort->window);
  2481. }
  2482.  
  2483.  
  2484. #ifdef __STDC__
  2485. extern void
  2486. xio_close_display (void)
  2487. #else
  2488. extern void
  2489. xio_close_display ()
  2490. #endif
  2491. {
  2492.   XCloseDisplay (thePort->dpy);
  2493.   x11_opened = 0;
  2494. }
  2495.  
  2496. #ifdef __STDC__
  2497. static void
  2498. xio_flush (void)
  2499. #else
  2500. static void
  2501. xio_flush ()
  2502. #endif
  2503. {
  2504.   XFlush (theDisplay);
  2505. }
  2506.  
  2507.  
  2508.  
  2509.  
  2510. #define _io_open_display xio_open_display
  2511. #define _io_redisp xio_redisp
  2512. #define _io_repaint xio_repaint
  2513. #define _io_repaint_win xio_repaint_win
  2514. #define _io_close_display xio_close_display
  2515. #define _io_input_avail xio_input_avail
  2516. #define _io_scan_for_input xio_scan_for_input
  2517. #define _io_wait_for_input xio_wait_for_input
  2518. #define _io_read_kbd xio_read_kbd
  2519. #define _io_nodelay xio_nodelay
  2520. #define _io_getch xio_getch
  2521. #define _io_bell xio_bell
  2522. #define _io_get_chr xio_get_chr
  2523. #define _io_update_status xio_update_status
  2524. #define _io_info_msg xio_info_msg
  2525. #define _io_error_msg xio_error_msg
  2526. #define _io_fix_input xio_fix_input
  2527. #define _io_move_cursor xio_move_cursor
  2528. #define _io_erase xio_erase
  2529. #define _io_insert xio_insert
  2530. #define _io_over xio_over
  2531. #define _io_flush xio_flush
  2532. #define _io_clear_input_before xio_clear_input_before
  2533. #define _io_clear_input_after xio_clear_input_after
  2534. #define _io_pr_cell_win xio_pr_cell_win
  2535. #define _io_hide_cell_cursor xio_hide_cell_cursor
  2536. #define _io_display_cell_cursor xio_display_cell_cursor
  2537. #define _io_cellize_cursor xio_cellize_cursor
  2538. #define _io_inputize_cursor xio_inputize_cursor
  2539.  
  2540.  
  2541. #ifdef __STDC__
  2542. void
  2543. x11_graphics (void)
  2544. #else
  2545. void
  2546. x11_graphics ()
  2547. #endif
  2548. {
  2549.   IO_SETUP;
  2550. }
  2551.  
  2552. #ifdef __STDC__
  2553. void
  2554. set_x_default_point_size (int l)
  2555. #else
  2556. void
  2557. set_x_default_point_size (l)
  2558.      int l;
  2559. #endif
  2560. {
  2561.   if (l > 4)
  2562.     {
  2563.       cell_font_point_size = l;
  2564.       {
  2565.     struct cell_gc *cgc = cell_gc (thePort, default_font(), 0);
  2566.     height_scale = cgc->font->ascent + cgc->font->descent;
  2567.     width_scale = cgc->font->max_bounds.width;
  2568.       }
  2569.       io_set_scr_size (scr_lines, scr_cols);
  2570.     }
  2571. }
  2572.  
  2573.  
  2574. #endif /* HAVE_X11_X_H */
  2575.  
  2576.